home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c++ / 750 < prev    next >
Encoding:
Internet Message Format  |  1996-08-06  |  4.4 KB

  1. From: jpotter@falcon.lhup.edu (John E. Potter)
  2. Message-ID: <4ih0eb$ms9@jake.esu.edu>
  3. X-Original-Date: 17 Mar 1996 12:26:51 GMT
  4. Path: in1.uu.net!bounce-back
  5. Date: 17 Mar 96 16:16:23 GMT
  6. Approved: fjh@cs.mu.oz.au
  7. Newsgroups: comp.std.c++
  8. Subject: Re: static_cast
  9. Organization: East Stroudsburg University, Pennsylvania
  10. References: <30F54E6D.B4@worldnet.att.net>
  11. X-Newsreader: TIN [version 1.2 PL2]
  12. X-Auth: PGPMoose V1.1 PGP comp.std.c++
  13.     iQBFAgUBMUw64eEDnX0m9pzZAQHwkgF+OxfIfslkMyjhgGjWalsVodwMxNRyEguR
  14.     IPPcoI5iXFLEzDU3QNi79EDxUVzrA+X2
  15.     =FoI9
  16.  
  17. alice yang (aliceyang@worldnet.att.net) wrote:
  18. : C++ Guru
  19. :  Would you help me to understand the importance of using "static-cast"?
  20.  
  21. I responded to this via e-mail.  Much the same as Kanze.  I also had a
  22. problem coming up with an example of static_cast.  The following prompted
  23. some concern that it could be infered that static_cast is useless.
  24.  
  25. > "when do I HAVE to use static_cast explicity".  It seems that c cast
  26. > can do the same thing anyway (as far as static-cast is concerned)
  27.  
  28. I also read James Kanze post to your question.  Seems that we agree mostly
  29. except that he prefers the C style since it clears ambiguities while I
  30. prefer the C++ functional style because it looks like an explicit
  31. constructor call.  We all know that that can not be done, but effectively
  32. that is what happens.  The technical rules are:
  33. float(intThing) ==> (float)intThing ==> static_cast<float>(intThing) ==>
  34. create an unnamed temporary float constructed by a standard conversion
  35. from int.  Wow!  By the way, it is an rvalue; so, this is not legal:
  36.  
  37. float floatThing = float(intThing) *= anotherThing;
  38.  
  39. However, had it been a class item rather than a built-in and *= were a
  40. member function, the above would be legal.  Non-const member functions
  41. may be used with rvalues.
  42.  
  43. I did think of an example where I would use static_cast; however, James
  44. would not need to.
  45.  
  46. long double ld = static_cast<long double>(intThing);
  47.  
  48. The C++ functional form of cast can not be used except with simple type
  49. identifiers.  Since I prefer function style casts, I always made a bunch
  50. of typedefs to allow their use.
  51.  
  52. typedef long double longDouble;
  53. long double ld = longDouble(intThing);
  54.  
  55. I think that I will shift from that to static_cast when my compilers all
  56. catch up to the new rules.  Only one of my four compilers currently
  57. support the new casts.
  58.  
  59. One word of caution.  In the above formal rules, the step from C style
  60. cast to new style cast has three possibilities.  The compiler must decide
  61. which is appropriate.  I generally do not trust compilers and prefer to
  62. be explicit.  Here is a nasty example.
  63.  
  64. Thing fun (const Thing& t) {
  65.     return Thing(t) += 10;
  66.     }
  67.  
  68. The class Thing has a constructor which takes an int.  Since t is of type
  69. thing, the cast calls for use of the copy constructor.  The class does have
  70. a member +=.  I said:
  71.  
  72.     return static_cast<Thing>(t) += /* implicit */ static_cast<Thing>(10);
  73.  
  74. The compiler heard:
  75.  
  76.     return const_cast<Thing>(t) += /* implicit */ static_cast<Thing>(10);
  77.  
  78. Boy was that a shock.  All of my const parameters got modified and gave
  79. total garbage for results.  The down side is that the compiler did not
  80. support the new casts so that I could not be explicit.  The real problem
  81. was that the compiler did not generate a copy constructor so it could
  82. not use a static_cast.  The rules say that there is always a copy
  83. constructor.  Some people, including compiler writers, think that
  84. declaring any constructor cancels both the generated default and
  85. copy constructors.  Any constructor, including the copy constructor,
  86. cancels the default constructor; however, there must always be a
  87. copy constructor.  There can be two but never none.  I solved my
  88. problem by declaring the copy constructor.
  89.  
  90. With compilers racing to catch the moving C++ standard, bugs like this
  91. will be around for a while.  If your compiler supports the new style
  92. casts, I would strongly recomend using them in place of C style or C++
  93. functional style.  An explicit conversion/copy constructor call sure looks
  94. nicer, but static_cast reminds us of what we are really doing.
  95.  
  96. John
  97. ---
  98. [ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
  99. [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
  100. [ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
  101. [ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
  102. [ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]
  103.